An operating system is the foundational software of a computer that may perform a wide variety of operations such as scheduling tasks, allocating storage, and interacting with various applications. Because they are so vital to the computers on which they execute, operating systems are often updated to provide a number of new and improved features. An operating system may be updated by releasing a new version of the operating system. For example, the Windows operating system from MICROSOFT Corp. of Redmond, Wash. has been released in a number of versions such as Windows Vista, Windows XP, Windows Me and Windows 2000. A newest version of an operating system may be referred to as a “native” system, while previous versions of the operating system may be referred to as “legacy” systems. Native systems may offer may offer several advantages to consumers in comparison with their legacy counterparts.
One problem related to updating of operating systems is that legacy binary programming modules (“legacy binaries”) designed to execute with legacy applications may not be completely compatible with the native operating system. In particular, a native operating system may be incapable of understanding and/or handling many of the legacy system calls that are made by legacy binaries. For example, in some cases, a legacy system call that once existed in a legacy operating system may no longer be valid in the native operating system. In other cases, a legacy system call may have a counterpart native system call, but the counterpart native system call may not be completely identical to the legacy system call. In addition to system calls, legacy binaries may be incapable of understanding and/or handling many of the callbacks and exceptions that are generated by a native operating system. For example, a native callback may implement behaviors that do not map to any existing legacy callback functions. Additionally, for example, the native operating system may generate an exception using a new layout that is not compatible with the legacy binaries.
One conventional approach to the legacy binary compatibility problem is to use native binaries rather than legacy binaries, and to load a “shim” program that sits between the legacy application and the native binaries. The shim program essentially translates various communications between the legacy application and the native binaries to provide compatibility between the legacy application and the native binaries. While shims offer a simple approach to alleviating the legacy binary compatibility problem, they also suffer from a number of limitations. In particular, shims are generated on an application-by-application basis and, therefore, lack scalability for large quantities of legacy applications.
Another conventional approach to the legacy binary compatibility problem is to execute the legacy application on a virtual machine that completely boots and runs on the legacy operating system. Enabling the legacy application to execute on a guest legacy operating system reduces the need for the legacy binaries to interact with the host native operating system. However, the use of virtual machines also creates several unwanted side effects by isolating the guest legacy operating system from the host native operating system, thereby making it difficult for the legacy application to access and share the resources of the host operating system.
Accordingly, what is needed is a scalable approach to the legacy binary compatibility problem that enables legacy binaries to interact efficiently with a native operating system while at the same time not restricting the accessibility of the native operating system's resources to the legacy application.